#pragma once
/*--------------------------------------------------------------------------------
 * Adaptive Intelligence - Foundation Framework Class Library
 * Version 2.00
 * 
 * Generic Collection Base C;ass
 *      Provides a base implementation for creating generics-based strongly-
 * typed collection classes.
 *------------------------------------------------------------------------------*/

/*--------------------------------------------------------------------------------
 * System Imports
 *------------------------------------------------------------------------------*/
#include "Stdafx.h"
#include "DisposableObjectBase.h"
#include "GenericCollectionBaseEnumerator.h"

using namespace System;
using namespace System::Collections;
using namespace System::Collections::Generic;

namespace Adaptive
{
	namespace Foundation
	{
		/// <summary>
		/// Provides a base implementation for creating generics-based strongly-
		/// typed collection classes.
		/// </summary>
		generic<typename T>
		public ref class GenericCollectionBase abstract : public DisposableObjectBase, public System::Collections::Generic::ICollection<T>
		{
		
        /*--------------------------------------------------------------------------------
         * Constructor / Dispose / Destructor Methods
         *------------------------------------------------------------------------------*/
		protected:	
			GenericCollectionBase();
			~GenericCollectionBase();
			!GenericCollectionBase();

			/*--------------------------------------------------------------------------------
			 * Protected Methods / Functions
			 *------------------------------------------------------------------------------*/
			/// <summary>
			/// Queries the implementing class to provide the key value for the specific 
			/// object instance.
			/// </summary>
			/// <param name="itemToGetKeyFor">
			/// The object instance to store in the collection for which a key is needed.
			/// </param>
			/// <returns>
			/// The key value to associate with the object once stored in the collection.
			/// </returns>
			virtual String^ GetKeyForObject(T itemToGetKeyFor) abstract;

		public:
			/*--------------------------------------------------------------------------------
			 * Public Properties
			 *------------------------------------------------------------------------------*/
			/// <summary>
			/// Gets the number of items currently stored in the collection.
			/// </summary>
			/// <value>
			/// The number of instances in the collection.
			/// </value>
			property int Count{ virtual int get(); };
			/// <summary>
			/// Gets the item at the specified index from the collection.
			/// </summary>
			/// <param name="index">
			/// The ordinal index of the item to be retrieved.
			/// </param>
			/// <returns>
			/// An object instance if found; otherwise, returns <b>null</b>.
			/// </returns>
			property T default[int] { virtual T get(int index); };
			/// <summary>
			/// Gets the item with the specified reference key from the collection.
			/// </summary>
			/// <param name="referenceKey">
			/// The reference key of the object to be retrieved.
			/// </param>
			/// <returns>
			/// An object instance if found; otherwise, returns <b>null</b>.
			/// </returns>
			property T default[String^] { virtual T get(String^ referenceKey); };
			/// <summary>
			/// Gets a value indicating whether the local enumeration has reached the
			/// end of the collection contents.
			/// </summary>
			/// <remarks>
			/// This property is not valid unless <see cref="MoveFirst()"/> or another enumeration 
			/// method has been called.
			/// </remarks>
			/// <value> 
			/// <b>true</b> if the end of the collection is reached; otherwise, <b>false</b>.
			/// </value>
			property bool Eof{ virtual bool get(); };
			/// <summary>
			/// Gets a value indicating whether the collection instance is a 
			/// read-only collection.
			/// </summary>
			/// <value>
			/// Returns <b>false</b>.
			/// </value>
			property bool IsReadOnly{ virtual bool get(); };
			/// <summary>
			/// Gets a value indicating whether the local enumeration has reached the
			/// item next to the end of the collection contents.
			/// </summary>
			/// <remarks>
			/// This property is not valid unless <see cref="MoveFirst()"/> or another enumeration 
			/// method has been called.
			/// </remarks>
			/// <value> 
			/// <b>true</b> if the end of the collection is reached; otherwise, <b>false</b>.
			/// </value>
			property bool NextToLast{ virtual bool get(); };
			/// <summary>
			/// Gets the reference to the object instance at the current position in the 
			/// local collection enumeration.
			/// </summary>
			/// <value>
			/// An object instance if the enumeration is active and <see cref="Eof"/> has not been 
			/// reached; otherwise, <b>null</b>.
			/// </value>
			/// <remarks>
			/// This property is not valid unless <see cref="MoveFirst()"/> or another enumeration 
			/// method has been called.
			/// </remarks>
			property T Value{ virtual T get(); };

			/*--------------------------------------------------------------------------------
			 * Public Methods / Functions
			 *------------------------------------------------------------------------------*/
			/// <summary>
			/// Appends a new object instance to the collection.
			/// </summary>
			/// <param name="itemToBeAdded">
			/// The object instance to store in the collection.
			/// </param>
			virtual void Add(T itemToBeAdded);
			/// <summary>
			/// Removes the contents of the collection.
			/// </summary>
			virtual void Clear();
			/// <summary>
			/// Removes all objects from the collection and calls the <b>Dispose</b> method
			/// on any <see cref="IDisposable"/> instances in the collection.
			/// </summary>
			virtual void ClearAndDispose();
			/// <summary>
			/// Explicit interface implementation.
			/// </summary>
			/// <returns></returns>
			virtual System::Collections::IEnumerator^ GetNonGenericEnumerator() = System::Collections::IEnumerable::GetEnumerator;
			/// <summary>
			/// Gets an enumerator for the collection.  To be overidden in descendant classes.
			/// </summary>
			/// <returns><b>null</b>.</returns>
			virtual System::Collections::Generic::IEnumerator<T>^ GetEnumerator() = System::Collections::Generic::IEnumerable<T>::GetEnumerator;
			/// <summary>
			/// Gets a value indicating whether the specified instance is already present
			/// in the collection.
			/// </summary>
			/// <param name="itemToFind">
			/// The object instance to be located.
			/// </param>
			/// <returns>
			/// <b>true</b>if the instance is present; otherwise, returns <b>false</b>.
			/// </returns>
			virtual bool Contains(T itemToFind);
			/// <summary>
			/// Copies the contents of the collection to the specified  array instance.
			/// </summary>
			/// <param name="arrayDestination">
			/// The array to copy the contents to.
			/// </param>
			/// <param name="startPosition">
			/// The position in the array at which to begin copying.
			/// </param>
			virtual void CopyTo(array<T,1>^ arrayDestination, int startPosition);
			/// <summary>
			/// Moves the local enumeration pointer to the first item in the collection.
			/// </summary>
			/// <remarks>
			/// This is for use with the <see cref="Eof"/> and <see cref="Value"/> properties.
			/// </remarks>
			void MoveFirst();
			/// <summary>
			/// Moves the local enumeration pointer to the last item in the collection.
			/// </summary>
			/// <remarks>
			/// This is for use with the <see cref="Eof"/> and <see cref="Value"/> properties.
			/// </remarks>
			void MoveLast();
			/// <summary>
			/// Moves the local enumeration pointer to the next item in the collection.
			/// </summary>
			/// <remarks>
			/// This is for use with the <see cref="Eof"/> and <see cref="Value"/> properties.
			/// </remarks>
			void MoveNext();
			/// <summary>
			/// Moves the local enumeration pointer to the previous item in the collection.
			/// </summary>
			/// <remarks>
			/// This is for use with the <see cref="Eof"/> and <see cref="Value"/> properties.
			/// </remarks>
			void MovePrevious();
			/// <summary>
			/// Removes the item at the specified index from the collection.
			/// </summary>
			/// <param name="index">
			/// The index of the object to be removed.
			/// </param>
			void Remove(int index);
			/// <summary>
			/// Removes the item with the specified reference key from the collection.
			/// </summary>
			/// <param name="referenceKey">
			/// The reference key of the instance to be removed.
			/// </param>
			void Remove(String^ referenceKey);
			/// <summary>
			/// Removes the specified object from the collection.
			/// </summary>
			/// <param name="itemToBeRemoved">
			/// The object instance to be removed.
			/// </param>
			/// <returns>b
			/// <b>true</b> if the object was removed; otherwise, <b>false</b>.
			/// </returns>
			virtual bool Remove(T itemToBeRemoved);

		private:
			/*--------------------------------------------------------------------------------
			 * Private Member Declarations
			 *------------------------------------------------------------------------------*/
			/// <summary>
			/// Storage of key and index values.
			/// </summary>
			Dictionary<String^, int>^ _keyList;
			/// <summary>
			/// Storage of actual values.
			/// </summary>
			List<T>^ _storage;
			/// <summary>
			/// Seperate enumeration value.
			/// </summary>
			int _currentIndex;
			/// <summary>
			/// Re-sets the key-and-index list.
			/// </summary>
			void ReorderKeys();

		};
	}
}